package com.cskaoyan.service.impl;

import com.cskaoyan.mapper.CartMapper;
import com.cskaoyan.mapper.CouponMapper;
import com.cskaoyan.mapper.CouponUserMapper;
import com.cskaoyan.model.*;
import com.cskaoyan.model.bo.BaseParamBO;
import com.cskaoyan.model.vo.DataVO;
import com.cskaoyan.model.vo.ExceptionVO;
import com.cskaoyan.model.vo.WxCouponVO;
import com.cskaoyan.service.WxCouponService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;


import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @ClassName: WxCouponServiceImpl
 * @Description: TODO 微信端优惠券实际业务操作
 * @Author:zk
 * @Date: 2022/5/8 20:47
 * @Version: 1.0
 **/
@Transactional
@Service
public class WxCouponServiceImpl implements WxCouponService {
    @Autowired
    CouponMapper couponMapper;
    @Autowired
    CouponUserMapper couponUserMapper;
    @Autowired
    CartMapper cartMapper;

    /**
     * @author: zk
     * @description: TODO 查询显示优惠券列表
     * @date: 2022/5/8 20:50
     */
    @Override
    public DataVO<Coupon> selectCouponList(BaseParamBO param) {
        Integer page = param.getPage();//页面序号
        Integer limit = param.getLimit();//页面容量

        param.setOrder("desc");
        param.setSort("add_time");
        String sort = param.getSort();//排序列
        String order = param.getOrder();//排序方式

        //分页工具
        PageHelper.startPage(page, limit);

        CouponExample couponExample = new CouponExample();
        couponExample.setOrderByClause(sort + " " + order);
        CouponExample.Criteria criteria = couponExample.createCriteria();
        //仅显示未被逻辑删除的
        criteria.andDeletedEqualTo(false);
        //仅显示正常可用的
        criteria.andStatusEqualTo((short) 0);

        List<Coupon> list = couponMapper.selectByExample(couponExample);

        //根据list得到分页信息
        int pages = PageInfo.of(list).getPages();
        long total = PageInfo.of(list).getTotal();
        return DataVO.data(total, pages, limit, page, list);
    }

    /**
     * @author: zk
     * @description: TODO 根据用户id和优惠券状态查询优惠券列表
     * @date: 2022/5/9 15:46
     */
    @Override
    public DataVO<WxCouponVO> selectMylistByStatus(BaseParamBO param, Integer status, Integer userId) {
        Integer page = param.getPage();
        Integer limit = param.getLimit();

        param.setSort("add_time");
        param.setOrder("desc");

        PageHelper.startPage(page, limit);

        List<WxCouponVO> list = couponMapper.selectUserCoupon(param, status, userId);

        PageInfo<WxCouponVO> pageInfo = new PageInfo<>(list);
        int pages = pageInfo.getPages();
        long total = pageInfo.getTotal();

        return DataVO.data(total, pages, limit, page, list);
    }

    /**
     * @author: zk
     * @description: TODO 领取优惠券
     * @date: 2022/5/9 19:17
     */
    @Override
    public ExceptionVO receiveCoupon(Integer userId, Coupon coupon) {
        Coupon couponInfo = couponMapper.selectByPrimaryKey(coupon.getId());
        //仅通用优惠券可供直接领取
        Short type = couponInfo.getType();
        if (type == (short) 1) {
            return ExceptionVO.error(740, "仅限注册时赠送");
        }
        if (type == (short) 2) {
            return ExceptionVO.error(740, "仅限兑换码领取");
        }
        //优惠券库存判断
        if (couponInfo.getTotal() == -1) {
            return ExceptionVO.error(740, "优惠券已领完");
        }
        //优惠券个人领取限制判断
        CouponUserExample couponUserExample = new CouponUserExample();
        CouponUserExample.Criteria criteria = couponUserExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andCouponIdEqualTo(couponInfo.getId());
        int count = (int) couponUserMapper.countByExample(couponUserExample);
        if (couponInfo.getLimit() != 0 && count >= couponInfo.getLimit()) {
            return ExceptionVO.error(740, "领取次数已用完");
        }

        //若此优惠券限量且库存仅存一个时,领取后将库存置-1 代表库存清空
        if (couponInfo.getTotal() == 1) {
            coupon.setTotal(-1);
            //领取优惠券
            insertCouponUser(userId, coupon);
            //库存清空
            couponMapper.updateByPrimaryKeySelective(coupon);
        }
        //若此优惠券不限量,则直接插入,对优惠券库存不做操作
        if (couponInfo.getTotal() == 0) {
            insertCouponUser(userId, coupon);
        }
        //若此优惠券限量且此次领取并不清空库存,则库存-1操作
        if (couponInfo.getTotal() != 0 && couponInfo.getTotal() != 1) {
            insertCouponUser(userId, coupon);
            coupon.setTotal(couponInfo.getTotal() - 1);
            couponMapper.updateByPrimaryKeySelective(coupon);
        }
        return ExceptionVO.fine();
    }

    @Override
    public ExceptionVO exchangeCoupon(Integer userId, Coupon coupon) {
        //根据兑换码获取优惠券信息
        CouponExample couponExample = new CouponExample();
        CouponExample.Criteria criteria = couponExample.createCriteria();
        criteria.andTypeEqualTo((short) 2);
        criteria.andCodeEqualTo(coupon.getCode());
        List<Coupon> coupons = couponMapper.selectByExample(couponExample);
        //若输入兑换码不存在,则显示兑换码错误
        if (coupons.isEmpty()) {
            return ExceptionVO.error(742, "兑换码不存在");
        }
        Coupon couponInfo = coupons.get(0);
        coupon.setId(couponInfo.getId());
        //优惠券库存判断
        if (couponInfo.getTotal() == -1) {
            return ExceptionVO.error(740, "优惠券已兑换完");
        }
        //优惠券个人领取限制判断
        CouponUserExample couponUserExample = new CouponUserExample();
        CouponUserExample.Criteria criteria2 = couponUserExample.createCriteria();
        criteria2.andUserIdEqualTo(userId);
        criteria2.andCouponIdEqualTo(couponInfo.getId());
        int count = (int) couponUserMapper.countByExample(couponUserExample);
        if (couponInfo.getLimit() != 0 && count >= couponInfo.getLimit()) {
            return ExceptionVO.error(740, "兑换次数已用完");
        }

        //若此优惠券限量且库存仅存一个时,领取后将库存置-1 代表库存清空
        if (couponInfo.getTotal() == 1) {
            coupon.setTotal(-1);
            //领取优惠券
            insertCouponUser(userId, coupon);
            //库存清空
            couponMapper.updateByPrimaryKeySelective(coupon);
        }
        //若此优惠券不限量,则直接插入,对优惠券库存不做操作
        if (couponInfo.getTotal() == 0) {
            insertCouponUser(userId, coupon);
        }
        //若此优惠券限量且此次领取并不清空库存,则库存-1操作
        if (couponInfo.getTotal() != 0 && couponInfo.getTotal() != 1) {
            insertCouponUser(userId, coupon);
            coupon.setTotal(couponInfo.getTotal() - 1);
            couponMapper.updateByPrimaryKeySelective(coupon);
        }
        return ExceptionVO.fine();


    }

    /**
     * @author: zk
     * @description: TODO  根据用户购物车选择可用优惠券列表
     * @date: 2022/5/9 22:51
     */
    @Override
    public DataVO<WxCouponVO> selectAvailableCouponList(Integer userId, Integer cartId) {
        BaseParamBO param = new BaseParamBO();
        param.setSort("add_time");
        param.setOrder("desc");
        //选出当前用户持有的可用优惠券列表
        List<WxCouponVO> list = couponMapper.selectUserCoupon(param, 0, userId);
        //若购物车id不为0,则是直接下单
        if (cartId != 0) {
            //获取购物车信息
            Cart cart = cartMapper.selectByPrimaryKey(cartId);
            double totalPrice = cart.getPrice() * cart.getNumber();
            //遍历列表选出满足消费金额可使用的优惠券
            for (WxCouponVO wxCouponVO : list) {
                if (totalPrice >= wxCouponVO.getMin().doubleValue()) {
                    wxCouponVO.setAvailable(true);
                }
            }
        }
        //若购物车id为0,则需要根据选中购物车列进行总和计算
        if (cartId == 0) {
            //根据选中状态和用户id进行筛选
            CartExample cartExample = new CartExample();
            CartExample.Criteria criteria = cartExample.createCriteria();
            criteria.andDeletedEqualTo(false);
            criteria.andCheckedEqualTo(true);
            criteria.andUserIdEqualTo(userId);
            List<Cart> carts = cartMapper.selectByExample(cartExample);
            double totalPrice = 0;
            for (Cart cart : carts) {
                double total = cart.getPrice() * cart.getNumber();
                totalPrice += total;
            }
            //遍历列表选出满足消费金额可使用的优惠券
            for (WxCouponVO wxCouponVO : list) {
                if (totalPrice >= wxCouponVO.getMin().doubleValue()) {
                    wxCouponVO.setAvailable(true);
                }
            }
        }

        return DataVO.data(list.size(), 1, list.size(), 1, list);
    }


    //领取优惠券的插入方法
    private void insertCouponUser(Integer userId, Coupon coupon) {
        //获取要领取的优惠券的信息
        Coupon couponInfo = couponMapper.selectByPrimaryKey(coupon.getId());
        //进行插入
        CouponUser couponUser = new CouponUser();
        couponUser.setUserId(userId);
        couponUser.setCouponId(coupon.getId());
        couponUser.setStatus((short) 0);
        couponUser.setAddTime(new Date());
        couponUser.setUpdateTime(new Date());
        couponUser.setDeleted(false);
        //根据优惠券有效时间类型确定有效时间
        if (couponInfo.getTimeType() == 0) {
            //基于领取时间的有效天数
            //获取有效期结束时间:领取时间+有效天数
            Calendar instance = Calendar.getInstance();
            instance.setTime(couponUser.getAddTime());
            instance.add(Calendar.DAY_OF_YEAR, couponInfo.getDays());
            Date endTime = instance.getTime();

            //设置有效时间startTime--endTime
            couponUser.setStartTime(couponUser.getAddTime());
            couponUser.setEndTime(endTime);
        }
        if (couponInfo.getTimeType() == 1) {
            //根据优惠券本身有效日期
            couponUser.setStartTime(couponInfo.getStartTime());
            couponUser.setEndTime(couponInfo.getEndTime());
        }
        //插入
        couponUserMapper.insert(couponUser);

    }


}
